﻿import numpy as np
import scipy.io as scio
import os
from deprecated import deprecated

# http://bci.med.tsinghua.edu.cn/download.html

'''
请不要使用这个类
这个是SSVEP方法，具体来说他是使用特定频率闪烁激发，而不是我们P300的范式
具体可查看该论文
https://kns.cnki.net/kcms2/article/abstract?v=LeTZRn7a1NLvGc7LrY8hoTPS0lXdAQiaQiEuoNys0TN1GxtbFERw59L3_eUBxsSwdvz854aA-eEVgape9M9-08EJRE47qlK-AWVBg8YXujlfGdYQ1bH4cfF2tmEe7ukLnYKSrkr3nx9EV45_hNizFA==&uniplatform=NZKPT&language=CHS
'''


@deprecated(reason="This class is deprecated.")
class LoadTsingHuaBCIDataSet:
    '''
    这个类用来加载TsingHua BCI数据
    
    Mat文件内容及格式：
    data    Double  64*1500*40*6    channel(Electrode index)*timePoint*targetIndex*blockIndex

    每个数据矩阵包含240次实验（40个目标*6个blocks），每次舒颜包含64个通道共1500个数据
    包含
        刺激前0.5秒
        刺激5秒
        刺激后0.5秒

    采样率 250Hz
        也就是说，秒数*250-1就可以获取数据
    
    刺激用的字符
    A   B   C   D   E   F   G   H
    I   J   K   L   M   N   O   P
    Q   R   S   T   U   V   W   X
    Y   Z   0   1   2   3   4   5
    6   7   8   9       ,   .   <-
    
    使用JFPM(Joint frequency-phase modulation)刺激方法，每个字符的频率/相位偏移
    8.0Hz/0π    9.0Hz/0.5π  10.0Hz/π    11.0Hz/1.5π 12.0Hz/0π   13.0Hz/0.5π 14.0Hz/π    15.0Hz/1.5π
    8.2Hz/0π    9.2Hz/0.5π  10.2Hz/π    11.2Hz/1.5π 12.2Hz/0π   13.2Hz/0.5π 14.2Hz/π    15.2Hz/1.5π
    8.4Hz/0π    9.4Hz/0.5π  10.4Hz/π    11.4Hz/1.5π 12.4Hz/0π   13.4Hz/0.5π 14.4Hz/π    15.4Hz/1.5π
    8.6Hz/0π    9.6Hz/0.5π  10.6Hz/π    11.6Hz/1.5π 12.6Hz/0π   13.6Hz/0.5π 14.6Hz/π    15.6Hz/1.5π
    8.8Hz/0π    9.8Hz/0.5π  10.8Hz/π    11.8Hz/1.5π 12.8Hz/0π   13.8Hz/0.5π 14.8Hz/π    15.8Hz/1.5π
    
    TargetIndex就是对应的标签
    '''

    def __init__(self,
                 filePath: str = None) -> None:
        super().__init__()
        self.filePath = filePath
        self.data = None
        self.MergeData = None

        if os.path.exists(self.filePath) and os.path.isfile(self.filePath):
            self.__LoadFile()

    def __LoadFile(self) -> None:
        '''
        简单的加载文件
        '''
        self.data = scio.loadmat(self.filePath)['data']

    def LoadFile(self,
                 filePath: str) -> np.ndarray | None:
        '''
        Description:
            加载Mat文件
            
        Parameters:
            filePath:str
                文件的路径
            
        Returns:
            date:np.ndarray|None
            文件路径正确时，返回Mat文件中的数组内容；否则为None
        '''
        if os.path.exists(filePath) and os.path.isfile(filePath):
            self.data = scio.loadmat(filePath)['data']
            return self.data
        else:
            return None

    def MergeBlock(self) -> np.ndarray:
        '''
        Description:
            将6次实验的数据进行合并，得到[64,1500,240]大小的数组
        
            每40次的实验堆加到前40个后
            索引对40取模就是对应的标签

        Returns:
            MergData:np.ndarray
            合并之后的数组
        '''
        self.MergData: np.ndarray = np.zeros((64, 1500, 240))
        for i in range(np.size(self.data, 3)):
            self.MergData[64, 1500, i * 40:i * 40 + 40] = self.data[64, 1500, 40, i]
        return self.MergData
